package com.sfac.hqyj.springBoot.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
@Aspect
public class ControllerAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerAspect.class);
    /*
    关联在方法上的切点，大面积额切入
     * -第一个 * 代表返回类型不限
     * -第二个 * 代表 module 下所有子包
     * -第三个 * 代表所有类
     * -第四个 * 代表所有方法
     * (..) 代表参数不限
     * Order 代表优先级，数字越小优先级越高
     */
    @Pointcut("execution(public * com.sfac.hqyj.springBoot.modules.*.controller.*.*(..))&&"+
            "!execution(public * com.sfac.hqyj.springBoot.modules.common.controller.WebSocketController.*(..))")
    @Order(1)
    public void controllerPointcut(){}

    @Before(value="controllerPointcut()")
    public void beforeController(JoinPoint joinPoint){
        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        LOGGER.debug(String.format("请求来源： %s",
                request.getRemoteAddr()));
        LOGGER.debug(String.format("请求路劲： %s",
                request.getRequestURI()));
        LOGGER.debug(String.format("请求方式： %s",
                request.getMethod()));
        LOGGER.debug(String.format("请求类： %s",
                joinPoint.getTarget().getClass().getName()));
        LOGGER.debug(String.format("请求方法： %s",
                joinPoint.getSignature().getName()));
        LOGGER.debug(String.format("请求参数： %s",
                joinPoint.getArgs() != null ? joinPoint.getArgs() : ""));
        LOGGER.debug("==== Before controller aspect ====");
    }

    @Around(value = "controllerPointcut()")
    public Object aroundController(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        LOGGER.debug("==== Aound controller aspect ====");
        return proceedingJoinPoint.proceed();
    }

    @After(value = "controllerPointcut()")
    public void afterController(JoinPoint joinPoint) {
        LOGGER.debug("==== After controller aspect ====");
    }

    @Around(value = "controllerPointcut()")
    public Object aroundAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        LOGGER.debug("==== Aound annotation aspect ====");
        long start = System.currentTimeMillis();
        Object object = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
        long end = System.currentTimeMillis();
        LOGGER.debug(String.format("目标方法执行时间： %s", (end - start)));
        return object;
    }
}
